package br.com.gr.jcash.ctr;

import br.com.gr.jcash.util.JsfUtil;
import br.com.gr.jcash.util.PaginationHelper;
import br.com.gr.jcash.dmp.Movimento;
import br.com.gr.jcash.exception.JCashException;
import br.com.gr.jcash.iface.IContaBO;
import br.com.gr.jcash.iface.IMovimentoBO;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;
import javax.inject.Named;

@Named(value = "movimentoController")
@SessionScoped
public class MovimentoController implements Serializable {

    @EJB
    private IMovimentoBO bo;
    @EJB
    private IContaBO contaBO;
    private Movimento current;
    private DataModel itens = null;
    private PaginationHelper pagination;
    private int selectedItemIndex;
    private String LIST = "list";
    private String CREATE = "create";
    private String VIEW = "view";
    private String EDIT = "edit";
    private List<SelectItem> selectContaOrigem;
    private List<SelectItem> selectContaDestino;
//    private List<String> sugestaoHistorico;

    public MovimentoController() {
    }

    public Movimento getSelected() {
        if (current == null) {
            current = new Movimento();
            selectedItemIndex = -1;
        }
        return current;
    }

    public void setSelected(Movimento movimento) {
        this.current = movimento;
    }

    private IMovimentoBO getFacade() {
        return bo;
    }

    public PaginationHelper getPagination() {
        if (pagination == null) {
            pagination = new PaginationHelper(7) {
                @Override
                public int getItemsCount() {
                    try {
                        return getFacade().count().intValue();
                    } catch (JCashException ex) {
                        Logger.getLogger(MovimentoController.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    return 0;
                }

                @Override
                public DataModel createPageDataModel() {
                    try {
                        return new ListDataModel(getFacade().buscarPorFaixa(new int[]{getPageFirstItem(), getPageFirstItem() + getPageSize()}));
                    } catch (JCashException ex) {
                        Logger.getLogger(MovimentoController.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    return null;
                }
            };
        }
        return pagination;
    }

    public String prepareList() {
        recreateModel();
        return LIST;
    }

    public String prepareView() {
        current = (Movimento) getItens().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItens().getRowIndex();
        return VIEW;
    }

    public String prepareCreate() {
        recreateSelectContaDestino();
        recreateSelectContaOrigem();
//        recreateSugestaoHistorico();
        current = new Movimento();
        selectedItemIndex = -1;
        return CREATE;
    }

    public String create() {
        try {
            getFacade().criar(current);
            JsfUtil.addSuccessMessage("Registro criado");
            return prepareCreate();
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, "Erro na persistência");
            return null;
        }
    }

    public String prepareEdit() {
        current = (Movimento) getItens().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItens().getRowIndex();
        return EDIT;
    }

    public String prepareEditFromView() {
        return EDIT;
    }

    public String update() {
        try {
            current = getFacade().editar(current);
            JsfUtil.addSuccessMessage("Registro alterado");
            return VIEW;
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, "Erro na persistência");
            return null;
        }
    }

    public String destroy() {
        current = (Movimento) getItens().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItens().getRowIndex();
        performDestroy();
        recreatePagination();
        recreateModel();
        return LIST;
    }

    public String destroyAndView() throws JCashException {
        performDestroy();
        recreateModel();
        updateCurrentItem();
        if (selectedItemIndex >= 0) {
            return VIEW;
        } else {
            // all itens were removed - go back to list
            recreateModel();
            return LIST;
        }
    }

    private void performDestroy() {
        try {
            getFacade().remover(current);
            JsfUtil.addSuccessMessage("Registro excluído");
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, "Erro na persistência");
        }
    }

    private void updateCurrentItem() throws JCashException {
        int count = getFacade().count().intValue();
        if (selectedItemIndex >= count) {
            // selected index cannot be bigger than number of itens:
            selectedItemIndex = count - 1;
            // go to previous page if last page disappeared:
            if (pagination.getPageFirstItem() >= count) {
                pagination.previousPage();
            }
        }
        if (selectedItemIndex >= 0) {
            current = getFacade().buscarPorFaixa(new int[]{selectedItemIndex, selectedItemIndex + 1}).get(0);
        }
    }

    public DataModel getItens() {
        if (itens == null) {
            itens = getPagination().createPageDataModel();
        }
        return itens;
    }

    private void recreateModel() {
        itens = null;
    }

    private void recreatePagination() {
        pagination = null;
    }

    public String next() {
        getPagination().nextPage();
        recreateModel();
        return LIST;
    }

    public String previous() {
        getPagination().previousPage();
        recreateModel();
        return LIST;
    }

    public SelectItem[] getItemsAvailableSelectMany() throws JCashException {
        return JsfUtil.getSelectItems(bo.buscarTodos(), false);
    }

    public SelectItem[] getItemsAvailableSelectOne() throws JCashException {
        return JsfUtil.getSelectItems(bo.buscarTodos(), true);
    }

    public String getNomeEntidade() {
        return "Movimento";
    }

    public List<SelectItem> getSelectContaOrigem() {
        if (selectContaOrigem == null) {
            selectContaOrigem = new ArrayList<>();
            recreateSelectContaOrigem();
        }
        return selectContaOrigem;
    }

    private void recreateSelectContaOrigem() {
        try {
            selectContaOrigem = JsfUtil.getSelectItemsGroupConta(contaBO.buscarContasOrigem(), true);
        } catch (JCashException ex) {
            Logger.getLogger(ContaController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public List<SelectItem> getSelectContaDestino() {
        if (selectContaDestino == null) {
            selectContaDestino = new ArrayList<>();
            recreateSelectContaDestino();
        }
        return selectContaDestino;
    }

    private void recreateSelectContaDestino() {
        try {
            selectContaDestino = JsfUtil.getSelectItemsGroupConta(contaBO.buscarContasDestino(), true);
        } catch (JCashException ex) {
            Logger.getLogger(ContaController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public IMovimentoBO getBo() {
        return bo;
    }

//    private void recreateSugestaoHistorico() {
//        try {
//            if (null == sugestaoHistorico) {
//                sugestaoHistorico = new ArrayList<>();
//            }
//            sugestaoHistorico = bo.buscarHistorico();
//
//        } catch (Exception e) {
//            Logger.getLogger(ContaController.class.getName()).log(Level.SEVERE, null, e);
//        }
//    }

//    public List<String> completeHistorico(String query) {
//        List<String> results = new ArrayList<>();
//
//        if (query.startsWith(" ")) {
//            results = this.sugestaoHistorico;
//        } else {
//            for (String historico : this.sugestaoHistorico) {
//                if (historico.startsWith(query)) {
//                    results.add(historico);
//                }
//            }
//        }
//        return results;
//    }
}
